package com.richard.library.basic.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.GradientDrawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;

import androidx.annotation.ColorInt;

import com.richard.library.basic.R;

/**
 * ShadowLayoutPro.java
 * <p>
 * Created by lijiankun on 17/8/11.
 */

public class ShadowLayout extends FrameLayout {

    public static final int ALL = 0x1111;

    public static final int LEFT = 0x0001;

    public static final int TOP = 0x0010;

    public static final int RIGHT = 0x0100;

    public static final int BOTTOM = 0x1000;

    public static final int SHAPE_RECTANGLE = 0x0001;

    public static final int SHAPE_OVAL = 0x0010;

    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private final RectF mRectF = new RectF();

    /**
     * 是否带阴影效果
     */
    private boolean is_shadow = true;

    /**
     * 阴影的颜色
     */
    private int mShadowColor = Color.TRANSPARENT;

    /**
     * 阴影的大小范围
     */
    private float mShadowRadius = 0;

    /**
     * 阴影 x 轴的偏移量
     */
    private float mShadowDx = 0;

    /**
     * 阴影 y 轴的偏移量
     */
    private float mShadowDy = 0;

    /**
     * 阴影显示的边界
     */
    private int mShadowSide = ALL;

    /**
     * 阴影的形状，圆形/矩形
     */
    private int mShadowShape = SHAPE_RECTANGLE;

    //背景视图相关
    private ImageView backgroundView;
    private GradientDrawable backgroundDrawable;
    private int shadowBackColor = Color.WHITE;//背景颜色，默认白色
    private int borderLineSize;//边框线大小
    private int borderLineColor;//边框线颜色

    public ShadowLayout(Context context) {
        this(context, null);
    }

    public ShadowLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ShadowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    /**
     * 读取设置的阴影的属性
     *
     * @param attrs 从其中获取设置的值
     */
    private void init(AttributeSet attrs) {
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);  // 关闭硬件加速
        this.setWillNotDraw(false);                    // 调用此方法后，才会执行 onDraw(Canvas) 方法

        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ShadowLayout);
        if (typedArray != null) {
            is_shadow = typedArray.getBoolean(R.styleable.ShadowLayout_is_shadow, true);
            mShadowColor = typedArray.getColor(R.styleable.ShadowLayout_shadowColor, getContext().getResources().getColor(android.R.color.black));
            mShadowRadius = typedArray.getDimension(R.styleable.ShadowLayout_shadowRadius, dip2px(0));
            mShadowDx = typedArray.getDimension(R.styleable.ShadowLayout_shadowDx, dip2px(0));
            mShadowDy = typedArray.getDimension(R.styleable.ShadowLayout_shadowDy, dip2px(0));
            mShadowSide = typedArray.getInt(R.styleable.ShadowLayout_shadowSide, ALL);
            mShadowShape = typedArray.getInt(R.styleable.ShadowLayout_shadowShape, SHAPE_RECTANGLE);
            shadowBackColor = typedArray.getColor(R.styleable.ShadowLayout_shadowBackColor, Color.WHITE);
            borderLineSize = typedArray.getDimensionPixelSize(R.styleable.ShadowLayout_borderLineSize, 0);
            borderLineColor = typedArray.getColor(R.styleable.ShadowLayout_borderLineColor, Color.TRANSPARENT);
            typedArray.recycle();
        }

        if (is_shadow) {
            setUpShadowPaint();
        }
        this.updateBackgroundView();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        float effect = mShadowRadius /*+ dip2px(5)*/;
        float rectLeft = 0;
        float rectTop = 0;
        float rectRight = this.getMeasuredWidth();
        float rectBottom = this.getMeasuredHeight();
        int paddingLeft = 0;
        int paddingTop = 0;
        int paddingRight = 0;
        int paddingBottom = 0;
        this.getWidth();
        if ((mShadowSide & LEFT) == LEFT) {
            rectLeft = effect;
            paddingLeft = (int) effect;
        }
        if ((mShadowSide & TOP) == TOP) {
            rectTop = effect;
            paddingTop = (int) effect;
        }
        if ((mShadowSide & RIGHT) == RIGHT) {
            rectRight = this.getMeasuredWidth() - effect;
            paddingRight = (int) effect;
        }
        if ((mShadowSide & BOTTOM) == BOTTOM) {
            rectBottom = this.getMeasuredHeight() - effect;
            paddingBottom = (int) effect;
        }
        if (mShadowDy != 0.0f) {
            rectBottom = rectBottom - mShadowDy;
            paddingBottom = paddingBottom + (int) mShadowDy;
        }
        if (mShadowDx != 0.0f) {
            rectRight = rectRight - mShadowDx;
            paddingRight = paddingRight + (int) mShadowDx;
        }
        mRectF.left = rectLeft;
        mRectF.top = rectTop;
        mRectF.right = rectRight;
        mRectF.bottom = rectBottom;
        this.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
    }

    /**
     * 真正绘制阴影的方法
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (is_shadow) {
            setUpShadowPaint();
            if (mShadowShape == SHAPE_RECTANGLE) {
                canvas.drawRect(mRectF, mPaint);
            } else if (mShadowShape == SHAPE_OVAL) {
                canvas.drawCircle(mRectF.centerX(), mRectF.centerY(), Math.min(mRectF.width(), mRectF.height()) / 2, mPaint);
            }
        }
    }

    private void setUpShadowPaint() {
        mPaint.reset();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.TRANSPARENT);
        mPaint.setShadowLayer(mShadowRadius, mShadowDx, mShadowDy, mShadowColor);
    }

    /**
     * dip2px dp 值转 px 值
     *
     * @param dpValue dp 值
     * @return px 值
     */
    private float dip2px(float dpValue) {
        DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
        float scale = dm.density;
        return (dpValue * scale + 0.5F);
    }

    /**
     * 更新背景视图
     */
    private void updateBackgroundView() {
        if (backgroundDrawable == null) {
            backgroundDrawable = new GradientDrawable();
        }

        backgroundDrawable.setCornerRadius(mShadowRadius);
        backgroundDrawable.setColor(shadowBackColor);
        if (borderLineSize >= 0) {
            backgroundDrawable.setStroke(borderLineSize, borderLineColor);
        }
        this.getBackgroundView().setBackground(backgroundDrawable);
    }

    /**
     * 获取背景视图View
     */
    private View getBackgroundView() {
        if (backgroundView == null) {
            backgroundView = new ImageView(getContext());
            this.addView(backgroundView, 0);
        }
        return backgroundView;
    }

    /**
     * 设置阴影颜色
     *
     * @param shadowColor 阴影颜色值 必须带透明度值
     */
    public void setShadowColor(int shadowColor) {
        if (mShadowColor != shadowColor) {
            mShadowColor = shadowColor;
            requestLayout();
            postInvalidate();
        }
    }

    /**
     * 设置阴影范围
     *
     * @param shadowRadius
     */
    public void setShadowRadius(float shadowRadius) {
        if (mShadowRadius != shadowRadius) {
            mShadowRadius = shadowRadius;
            requestLayout();
            postInvalidate();
        }
    }

    /**
     * 设置x轴和y轴偏移量
     *
     * @param shadowDx x轴偏移量
     * @param shadowDy y轴偏移量
     */
    public void setShadowDXY(float shadowDx, float shadowDy) {
        if (mShadowDx != shadowDx || mShadowDy != shadowDy) {
            mShadowDx = shadowDx;
            mShadowDy = shadowDy;
            requestLayout();
            postInvalidate();
        }
    }

    /**
     * 设置是否带阴影效果
     */
    public void setIs_shadow(boolean is_shadow) {
        if (this.is_shadow != is_shadow) {
            this.is_shadow = is_shadow;
            requestLayout();
            postInvalidate();
        }
    }


    /**
     * 设置阴影形状
     *
     * @param shadowShape ShadowLayout.SHAPE_RECTANGLE、ShadowLayout.SHAPE_OVAL
     */
    public void setShadowShape(int shadowShape) {
        if (mShadowShape != shadowShape) {
            mShadowShape = shadowShape;
            requestLayout();
            postInvalidate();
        }
    }

    /**
     * 设置阴影的边
     *
     * @param shadowSide description :
     *                   ShadowLayout.ALL
     *                   ShadowLayout.LEFT
     *                   ShadowLayout.TOP
     *                   ShadowLayout.RIGHT
     *                   ShadowLayout.BOTTOM
     */
    public void setShadowSide(int shadowSide) {
        if (mShadowSide != shadowSide) {
            mShadowSide = shadowSide;
            requestLayout();
            postInvalidate();
        }
    }

    /**
     * 设置边框线样式
     *
     * @param borderLineSize  边框线大小 px
     * @param borderLineColor 边框线颜色值
     */
    public void setBorderLineStyle(int borderLineSize, @ColorInt int borderLineColor) {
        this.borderLineSize = borderLineSize;
        this.borderLineColor = borderLineColor;
        this.updateBackgroundView();
    }

    /**
     * 设置背景颜色
     */
    public void setBackgroundColor(@ColorInt int color) {
        this.shadowBackColor = color;
        this.updateBackgroundView();
    }
}

